#include "rocc.h"
#include "util.h"

struct CIMparam{
        uint32_t push_start;
        uint32_t push_num ;
        uint32_t save_start;
        uint32_t save_num ;
        uint32_t mvm_array_index;
        uint32_t mvm_row_start;
        uint32_t mvm_col_start;
        uint32_t mvm_row_num;
        uint32_t mvm_col_num;
        uint32_t conf_random;
        uint32_t conf_wisenum;
        uint32_t conf_outshift;
        uint32_t conf_cimshift;
}cp;

struct RoCCparam{
        uint64_t push_rs2;
        uint64_t save_rs2;
        uint64_t mvm_rs2;
        uint64_t mvm_rs1;
        uint64_t config;
}rp;

void RoCCparamInit(struct CIMparam * cim,struct RoCCparam * rocc){
	rocc->push_rs2 = cim->push_start <<11    | cim->push_num;
	rocc->save_rs2 = cim->save_start <<11    | cim->save_num;
	rocc->mvm_rs1  = cim->mvm_row_num<<16    | cim->mvm_col_num;
	rocc->mvm_rs2  = cim->mvm_array_index<<22| cim->mvm_row_start<<11|cim->mvm_col_start;
	rocc->config   = cim->conf_random<<23    | cim->conf_wisenum<<16 
					|cim->conf_outshift<<8   | cim->conf_cimshift;
}


#define ROCC_config(config) \
ROCC_INSTRUCTION_SS(0,config,0,2)

#define ROCC_push(addr,push_rs2) \
    __asm__ __volatile("fence");			\
ROCC_INSTRUCTION_SS(0,addr,push_rs2,17); \
    __asm__ __volatile("fence":::"memory")

#define ROCC_mvm(num_config,start_index) \
ROCC_INSTRUCTION_SS(0,num_config,start_index,1)

#define ROCC_save(addr,save_rs2) \
        __asm__ __volatile("fence");                  \
        ROCC_INSTRUCTION_SS(0,addr,save_rs2,18); \
        __asm__ __volatile("fence":::"memory")

#define RoCC_mac(rd,rs1,rs2)\
        __asm__ __volatile("fence");\
        ROCC_INSTRUCTION_DSS(1,rd,rs1,rs2,1);\
        __asm__ __volatile("fence":::"memory")

#define ROCC_initreg(addr,value) \
        __asm__ __volatile("fence");                  \
        ROCC_INSTRUCTION_SS(0,addr,value,3); \
        __asm__ __volatile("fence":::"memory")


